library flutter_bmfbase.map.bmf_models;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

// 此文件定义flutter与native间的基础数据交互中间层model

/// flutter_bmfmap 抽象类
abstract class BMFModel {
  /// model -> map
  @required
  Map<String, Object?> toMap();

  /// map -> dynamic
  @required
  dynamic fromMap(Map map);
}

/// 代表经纬度
class BMFCoordinate implements BMFModel {
  static BMFCoordinate coordinate() => BMFCoordinate(0, 0);

  /// 纬度
  double latitude;

  /// 经度
  double longitude;

  /// BMFCoordinate构造方法
  BMFCoordinate(this.latitude, this.longitude);

  // /// json -> BMFCoordinate
  // BMFCoordinate.fromJson(Map<String, dynamic> json) {
  //   latitude = json['latitude'];
  //   longitude = json['longitude'];
  // }

  // ///  BMFCoordinate -> json
  // Map<String, dynamic> toJson() {
  //   final Map<String, dynamic> data = new Map<String, dynamic>();
  //   data['latitude'] = this.latitude;
  //   data['longitude'] = this.longitude;
  //   return data;
  // }

  @override
  Map<String, Object> toMap() {
    return {'latitude': this.latitude, 'longitude': this.longitude};
  }

  @override
  fromMap(Map map) {
    if (null == map) {
      return null;
    }
    return new BMFCoordinate(map['latitude'], map['longitude']);
  }
}

/// 屏幕坐标
class BMFPoint implements BMFModel {
  /// 默认值 point =（0, 0）
  static BMFPoint point() => BMFPoint(0, 0);

  /// 横坐标
  double x;

  /// 纵坐标
  double y;

  /// BMFPoint构造方法
  BMFPoint(this.x, this.y);

  /// 屏幕坐标 -> map
  @override
  Map<String, Object> toMap() {
    return {'x': this.x, 'y': this.y};
  }

  /// map ->屏幕坐标
  @override
  fromMap(Map map) {
    if (null == map) {
      return null;
    }

    return new BMFPoint(map['x'], map['y']);
  }
}

/// 矩形大小，用直角地理坐标表示
class BMFSize implements BMFModel {
  /// 默认值 size =（0，0）
  static BMFSize size() => BMFSize(0, 0);

  /// 宽度
  double width;

  /// 高度
  double height;

  /// BMFSize构造方法
  BMFSize(this.width, this.height);

  /// BMFSize -> map
  @override
  Map<String, Object> toMap() {
    return {'width': this.width, 'height': this.height};
  }

  /// map -> BMFSize
  @override
  fromMap(Map map) {
    if (null == map) {
      return null;
    }

    return new BMFSize(map['width'], map['height']);
  }
}

/// 矩形，用直角地理坐标表示
class BMFMapRect implements BMFModel {
  /// 默认值{origin =（0，0), size = (0, 0)}
  static BMFMapRect rect() => BMFMapRect(BMFPoint(0, 0), BMFSize(0, 0));

  /// 屏幕左上点对应的直角地理坐标
  BMFPoint? origin;

  /// 坐标范围
  BMFSize? size;

  /// BMFMapRect构造方法
  BMFMapRect(this.origin, this.size);

  /// map -> BMFMapRect
  @override
  fromMap(Map map) {
    if (null == map) {
      return null;
    }

    return new BMFMapRect(BMFPoint.point().fromMap(map['origin']),
        BMFSize.size().fromMap(map['size']));
  }

  /// BMFMapRect -> map
  @override
  Map<String, Object?> toMap() {
    return {
      'origin':this.origin?.toMap(),
      'size': this.size?.toMap(),
    };
  }
}

/// 表示一个经纬度范围
class BMFCoordinateSpan implements BMFModel {
  /// 默认值 span = (0, 0)
  static BMFCoordinateSpan span() => BMFCoordinateSpan(0, 0);

  /// 纬度范围
  final double latitudeDelta;

  /// 经度范围
  final double longitudeDelta;

  /// BMFCoordinateSpan构造方法
  const BMFCoordinateSpan(this.latitudeDelta, this.longitudeDelta);

  /// 经纬度范围 -> map
  @override
  Map<String, Object> toMap() {
    return {
      'latitudeDelta': this.latitudeDelta,
      'longitudeDelta': this.longitudeDelta
    };
  }

  /// map -> 经纬度范围
  @override
  fromMap(Map map) {
    if (null == map) {
      return null;
    }
    return new BMFCoordinateSpan(map['latitudeDelta'], map['longitudeDelta']);
  }
}

/// 表示一个经纬度区域
class BMFCoordinateRegion implements BMFModel {
  /// 默认值 region = {latLng = (0, 0), span = (0, 0)}
  static BMFCoordinateRegion region() => BMFCoordinateRegion(
      center: BMFCoordinate.coordinate(), span: BMFCoordinateSpan.span());

  /// 中心点经纬度坐标
  final BMFCoordinate? center;

  /// 经纬度范围
  final BMFCoordinateSpan? span;

  /// BMFCoordinateRegion构造方法
  const BMFCoordinateRegion({this.center, this.span});

  /// 经纬度区域 -> map
  @override
  Map<String, Object?> toMap() {
    return {
      'center': this.center?.toMap(),
      'span': this.span?.toMap()
    };
  }

  /// map -> 经纬度区域
  @override
  fromMap(Map map) {
    if (null == map) {
      return null;
    }

    return new BMFCoordinateRegion(
        center: BMFCoordinate.coordinate().fromMap(map['center']),
        span: BMFCoordinateSpan.span().fromMap(map['span']));
  }
}

/// 表示一个经纬度边界范围
class BMFCoordinateBounds implements BMFModel {
  static BMFCoordinateBounds coordinateBounds() =>
      BMFCoordinateBounds(northeast: null, southwest: null);

  /// 该地理范围东北坐标
  BMFCoordinate? northeast;

  /// 该地理范围西南坐标
  BMFCoordinate? southwest;

  /// BMFCoordinateBounds构造方法
  BMFCoordinateBounds({this.northeast, @required this.southwest});

  /// 经纬度边界 -> map
  @override
  Map<String, Object> toMap() {
    return {'northeast': northeast!.toMap(), 'southwest': southwest!.toMap()};
  }

  /// map ->经纬度边界
  @override
  fromMap(Map map) {
    if (null == map) {
      return null;
    }
    return new BMFCoordinateBounds(
        northeast: BMFCoordinate.coordinate().fromMap(map['northeast']),
        southwest: BMFCoordinate.coordinate().fromMap(map['southwest']));
  }
}

/// 边框的插入距离(正值就是往内缩.负值就是往外扩充)
class BMFEdgeInsets implements BMFModel {
  static BMFEdgeInsets edgeInsets() =>
      BMFEdgeInsets(top: 0, left: 0, bottom: 0, right: 0);

  /// 上边距
  double? top;

  /// 左边距
  double? left;

  /// 下边距
  double? bottom;

  /// 右边距
  double? right;

  /// BMFEdgeInsets构造方法
  BMFEdgeInsets({
    this.top,
    this.left,
    this.bottom,
    this.right,
  });

  /// EdgeInsets => BMFEdgeInsets
  fromEdgeInsets(EdgeInsets insets) {
    return new BMFEdgeInsets(
        top: insets.top,
        left: insets.left,
        bottom: insets.bottom,
        right: insets.right);
  }

  @override
  fromMap(Map map) {
    if (null == map) {
      return null;
    }

    return new BMFEdgeInsets(
        top: map['top'],
        left: map['left'],
        bottom: map['bottom'],
        right: map['right']);
  }

  @override
  Map<String, Object?> toMap() {
    return {
      'top': this.top,
      'left': this.left,
      'bottom': this.bottom,
      'right': this.right
    };
  }
}
